﻿// Copyright (C) 2009  Lex Li
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using Lextm.M8Pack.ThemeBuilder.Properties;
using ShineOn.Rtl;

namespace Lextm.M8Pack.ThemeBuilder
{
    internal class Theme
    {
        private string _author;
        private int _showDate;
        private readonly string _working;
        private readonly string _package;
        private readonly IDictionary<string, string> _icons = new Dictionary<string, string>();

        public Theme(string fileName, string packageFolder, string workingFolder)
        {
            if (fileName == null)
            {
                throw new ArgumentNullException("fileName");
            }

            _working = workingFolder;
            _package = packageFolder; 
            
            if (Directory.Exists(_working))
            {
                foreach (string file in Directory.GetFiles(_working))
                {
                    File.SetAttributes(file, FileAttributes.Normal);
                    // File.Delete(file);
                }
                
                Directory.Delete(_working, true);
            }

            Directory.CreateDirectory(_working);
            using (TIniFile doc = new TIniFile(fileName))
            {
                _author = doc.ReadString(Resources.InfoSectionName, Resources.AuthorPropertyName, Resources.DefaultAuthorName);
                TStrings lines = new TStringList();
                doc.ReadSection(Resources.AppIconsSectionName, lines);
                for (int i = 0; i < lines.Count; i++)
                {
                    string key = lines[i];
                    string standard = string.Format(Resources.PngMask, key);
                    CopyImage(doc.ReadString(Resources.AppIconsSectionName, key, string.Empty), standard);
                    _icons.Add(key, standard);
                }
                
                _showDate = doc.ReadInteger("Other", "CalendarShowDate", 0);

                doc.Free();
            }

            CopyBackground(Resources.DesktopFileName, Resources.DesktopFileName);
            CopyBackground(Resources.StandbyFileName, Resources.StandbyFileName);
        }
        
        private void CopyImage(string origin, string destination)
        {
            if (!File.Exists(Path.Combine(_package, origin)))
            {
                return;
            }

            string newFile = Path.Combine(_working, destination);
            File.Copy(Path.Combine(_package, origin), newFile, true);
            new FileInfo(newFile).Attributes = FileAttributes.Normal;
        }
        
        private void CopyBackground(string origin, string destination)
        {
            string newFile = Path.Combine(_working, destination);
            if (!File.Exists(Path.Combine(_package, origin)))
            {
                Resources.background.Save(newFile);
                return;
            }
            
            File.Copy(Path.Combine(_package, origin), newFile, true);
            new FileInfo(newFile).Attributes = FileAttributes.Normal;
        }
        
        public string BackgroundImage
        {
            get { return GetFile(Resources.DesktopFileName); }
        }
        
        public string StandbyBackgroundImage
        {
            get { return GetFile(Resources.StandbyFileName); }
        }

        private string PreviewImage
        {
            get { return GetFile(Resources.PreviewLargeFileName); }
        }

        private string SmallPreviewImage
        {
            get { return GetFile(Resources.PreviewSmallFileName); }
        }
        
        public string GetFile(string shortName)
        {
            return Path.Combine(_working, shortName);
        }
        
        public void ReplaceBackground(string fileName)
        {
            // TODO: add backup feature.
            File.Copy(fileName, BackgroundImage, true);
        }
        
        public void ReplaceStandbyBackground(string fileName)
        {
            // TODO: add backup feature.
            File.Copy(fileName, StandbyBackgroundImage, true);
        }
        
        public void ReplaceIcon(string iconName, string fileName)
        {
            if (!Icons.ContainsKey(iconName))
            {
                Icons.Add(iconName, string.Format(Resources.PngMask, iconName));
            }
            
            string icon = Icons[iconName];
            // TODO: add backup feature.
            File.Copy(fileName, GetFile(icon), true);
        }

        public void Persist()
        {
            string temp = Path.GetTempFileName();
            using (TIniFile doc = new TIniFile(temp))
            {
                doc.WriteString(Resources.InfoSectionName, Resources.AuthorPropertyName, _author);
                foreach (string key in _icons.Keys)
                {
                    doc.WriteString(Resources.AppIconsSectionName, key, _icons[key]);
                }
                
                doc.WriteInteger("Other", "CalendarShowDate", _showDate);

                doc.UpdateFile();
                doc.Free();
            }
            
            // IMPORTANT: work around M8 ThemeManager bug
            using (StreamReader reader = new StreamReader(temp))
            {
                using (StreamWriter writer = new StreamWriter(GetFile(Resources.CfgFileName)))
                {
                    string line;
                    while ((line = reader.ReadLine()) != null)
                    {
                        if (line.Length > 1)
                        {
                            writer.WriteLine(line);
                        }
                    }

                    writer.Close();
                }
                
                reader.Close();
            }
        }

        public IDictionary<string, string> Icons
        {
            get { return _icons; }
        }
        
        public string Author
        {
            get { return _author; }
            set { _author = value; }
        }

        public void AddPreview(Image image)
        {
            image.Save(PreviewImage, ImageFormat.Jpeg);
            using (Bitmap small = new Bitmap(image, 120, 180))
            {
                small.Save(SmallPreviewImage, ImageFormat.Jpeg);
            }
        }
    }
}
